package com.pic.mgt.syushin.action;

import java.io.File;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.springframework.dao.DataAccessException;

import com.pic.mgt.IgxStatus;
import com.pic.mgt.action.AbstractMissUnitInspectActionImpl;
import com.pic.mgt.action.BusinessRecoverAction;
import com.pic.mgt.dao.syushin.ISyushinBusinessMgtDao;
import com.pic.mgt.dao.syushin.SyushinBusinessMgtInfoBean;
import com.pic.mgt.log.IgxLog;

public class SyushinMissBusinessUnitInspectActionImpl extends
		AbstractMissUnitInspectActionImpl {
	
	private BusinessRecoverAction syushinBusinessRecoverAction;
	
	private ISyushinBusinessMgtDao syushinBusinessMgtDao;
	
	private String syushinInspectBizInboxFolderStr;
	private String syushinInspectBizOutboxRealFolderStr;
	private long syushinInspectThreshold;
	private String bizConfirmationFilenameSuffix; 
	
	@Override
	public synchronized boolean inspectMissUnitAndRecover() {
		// ********************** Log **********************
		IgxLog.messageLog.info(this, "Starting miss business inspection process.");
		// ********************** Log **********************
		
		// 取得現在時間
		Date nowDate = new Date();
		
		
		// (1) 檢測 syushin inbox 目錄下的業務確認檔(包含read和batch)是否有存在超過指定的時間
		SuffixFilenameFilter bizConfirmationFilenameFilter = new SuffixFilenameFilter(this.bizConfirmationFilenameSuffix);
		File[] missBusinessConfirmationFileArray =
			super.checkFileMissUnderFolder(new File(this.syushinInspectBizInboxFolderStr),
										   nowDate,
										   this.syushinInspectThreshold,
										   bizConfirmationFilenameFilter);
		if (null != missBusinessConfirmationFileArray) {
			for (File missBusinessConfirmationFile : missBusinessConfirmationFileArray) {
				long missBizConfirmationFilesize = missBusinessConfirmationFile.length();
				
				// 如果開啟忽略 0KB 檔案的功能,則要做檢查
				if (super.isIgnoreEmptyBizConfirmationFile) {
					if (missBizConfirmationFilesize <= 0) {
						continue; // 表0KB的確認檔,則忽略之
					}
				}
				
				/*
				 * 如果確認檔的大小大於 0KB,則再做一次判斷這個確認檔是不是已經超過指定的時間。
				 * 
				 * 要這麼做的原因是因為，如果檔案送過來時失敗了(有檔但大小為0KB)，這時通常端末自己
				 * 會有 Retry 機制，可能會重傳。而在這裡做如果大於 0KB 的話則要再確認一次的原因，
				 * 就是要避免可能在此時，端末正在重傳了(所以大小不會為0KB了，同時檔案的時間也會
				 * 被更新)，會導致這次的重傳完畢了被系統偵測到，然後處理掉，這時如果再 recovery
				 * 就會有問題。
				 */
				if (missBizConfirmationFilesize > 0) {
					boolean isFileExistedOverTime =
						super.isFileExistedOverTime(missBusinessConfirmationFile,
													nowDate,
													this.syushinInspectThreshold);
					if (!isFileExistedOverTime) {
						continue;
					}
				}
								
				// --------- 確認檔案存在超過指定時間,以下開始做判斷和處理 --------------
				
				// 先取得 target file name
				String targetFilename = StringUtils.removeEnd(
											missBusinessConfirmationFile.getName(),
											this.bizConfirmationFilenameSuffix);
				
				// 從資料庫中取得該筆業務的記錄
				SyushinBusinessMgtInfoBean syushinBusinessMgtInfoBean;
				try {
					syushinBusinessMgtInfoBean =
							this.syushinBusinessMgtDao.findSyushinBusinessMgtInfoByUnitName(targetFilename);
				} catch (DataAccessException e) {
					// ********************** Log **********************
					IgxLog.messageDetailsLog.error(this, e.getMessage());
					// ********************** Log **********************
					
					// ********************** Log **********************
					IgxLog.messageLog.error(this,
									"SUDA-329 Miss business inspection　process failed due to database error.");
					// ********************** Log **********************
					
					return false;
				}
				if (null != syushinBusinessMgtInfoBean &&
					syushinBusinessMgtInfoBean.getStatus().equals(IgxStatus.BUSINESS_FAILED) ) {
					/*
					 * 如果業務是 BUSINESS_FAILED，表示上次執行有執行完成，只是因為某些原因 fail 掉，
					 * 所以不算是 miss 的業務。
					 */
					continue; // 跳離，直接處理下一個業務
				}
				
				// ********************** Log **********************
				IgxLog.messageLog.info(this,
						"Miss Business Inspection: detected a miss business '{}'.",
						missBusinessConfirmationFile.getAbsolutePath());
				// ********************** Log **********************
				
				// 進行業務恢復
				
				// 先取得目標檔案
				File targetFile = new File(
								StringUtils.removeEnd(missBusinessConfirmationFile.getAbsolutePath(),
													  this.bizConfirmationFilenameSuffix)); 
				this.syushinBusinessRecoverAction.recoverBusiness(targetFile.getName());
			}
		}
		
		// (送多方刪除)
		// (2) 檢測 syushin outbox real 目錄下的業務確認暫存檔,是否有存在超過指定的時間
		/*String bizTmpConfirmationFilenameSuffix = this.bizConfirmationFilenameSuffix + SimpleConfirmationFileMaker.tmpFileOkSuffixString;
		SuffixFilenameFilter bizTmpConfirmationFilenameFilter = new SuffixFilenameFilter(bizTmpConfirmationFilenameSuffix);
		missBusinessConfirmationFileArray =
			super.checkFileMissUnderFolder(new File(this.syushinInspectBizOutboxRealFolderStr),
										   nowDate,
										   this.syushinInspectThreshold,
										   bizTmpConfirmationFilenameFilter);
		if (null != missBusinessConfirmationFileArray) {
			for (File missBusinessConfirmationFile : missBusinessConfirmationFileArray) {
				
				// 先取得 target file name
				String targetFilename = StringUtils.removeEnd(
											missBusinessConfirmationFile.getName(),
											bizTmpConfirmationFilenameSuffix);
				
				// 從資料庫中取得該筆業務的記錄
				SyushinBusinessMgtInfoBean syushinBusinessMgtInfoBean;
				try {
					syushinBusinessMgtInfoBean =
							this.syushinBusinessMgtDao.findSyushinBusinessMgtInfoByUnitName(targetFilename);
				} catch (DataAccessException e) {
					// ********************** Log **********************
					IgxLog.messageDetailsLog.error(this, e.getMessage());
					// ********************** Log **********************
					
					// ********************** Log **********************
					IgxLog.messageLog.error(this,
									"SUDA-329 Miss business inspection　process failed due to database error.");
					// ********************** Log **********************
					
					return false;
				}
				if (null != syushinBusinessMgtInfoBean &&
					syushinBusinessMgtInfoBean.getStatus().equals(IgxStatus.BUSINESS_FAILED) ) {
					
					 * 如果業務是 BUSINESS_FAILED，表示上次執行有執行完成，只是因為某些原因 fail  掉，
					 * 所以不算是 miss 的業務。
					 
					continue; // 跳離，直接處理下一個業務
				}
				
				// ********************** Log **********************
				IgxLog.messageLog.info(this,
						"Miss Business Inspection: detected a miss business '{}'.",
						missBusinessConfirmationFile.getAbsolutePath());
				// ********************** Log **********************

				
				// 進行業務恢復
				
				// 先取得目標檔案
				File targetFile = new File(
								StringUtils.removeEnd(missBusinessConfirmationFile.getAbsolutePath(),
													  bizTmpConfirmationFilenameSuffix)); 
				this.syushinBusinessRecoverAction.recoverBusiness(targetFile.getName());
			}
		}*/
		
		// ********************** Log **********************
		IgxLog.messageLog.info(this, "Miss business inspection process completed.");
		// ********************** Log **********************
		
		return true;
	}
	
	// --- getter and setter ---

	public void setSyushinBusinessRecoverAction(
			BusinessRecoverAction syushinBusinessRecoverAction) {
		this.syushinBusinessRecoverAction = syushinBusinessRecoverAction;
	}

	public void setSyushinInspectBizInboxFolderStr(
			String syushinInspectBizInboxFolderStr) {
		this.syushinInspectBizInboxFolderStr = syushinInspectBizInboxFolderStr;
	}

	public void setSyushinInspectBizOutboxRealFolderStr(
			String syushinInspectBizOutboxRealFolderStr) {
		this.syushinInspectBizOutboxRealFolderStr = syushinInspectBizOutboxRealFolderStr;
	}

	public void setSyushinInspectThreshold(long syushinInspectThreshold) {
		this.syushinInspectThreshold = syushinInspectThreshold;
	}

	public void setBizConfirmationFilenameSuffix(
			String bizConfirmationFilenameSuffix) {
		this.bizConfirmationFilenameSuffix = bizConfirmationFilenameSuffix;
	}

	public void setSyushinBusinessMgtDao(
			ISyushinBusinessMgtDao syushinBusinessMgtDao) {
		this.syushinBusinessMgtDao = syushinBusinessMgtDao;
	}

}
